﻿/*******************************************************************************
* File Name  : NFPlayerBase.h
* Description: 
* Author     : gaoyi_ds
* Time       : 2024-07-29
* Version    : 1.0
* History:
* <author>      <time>      <version >  <desc>
*******************************************************************************/

#pragma once

#include <proto_cs.pb.h>
#include <NFComm/NFShmStl/NFShmBitMap.h>

#include "proto_common_attr.nanopb.h"
#include "proto_common_role.nanopb.h"
#include "NFComm/NFObjCommon/NFISaveDb.h"
#include "NFLogicCommon/NFCacheStatus.h"

namespace proto_ff
{
    class tbRoleDetail;
}

struct RoleBase;

class NFPlayerBase : public NFISaveDb, public NFCacheStatus
{
public:
    NFPlayerBase();

    virtual ~NFPlayerBase();

    int CreateInit();

    int ResumeInit();

public:
    static int MakeRoleInitData(proto_ff::RoleBase* pRoleBase, uint64_t ullRoleId, const char* pszName, int iActorId);

public:
    virtual int Init();

    virtual int UnInit();

    /**
     * @brief
     * @param data
     * @return
     */
    virtual int LoadFromDB(const proto_ff::tbRoleDetail* pDbData, const RoleOne& stRoleOne);

    /**
     * @brief
     * @param data
     * @return
     */
    virtual int InitConfig(proto_ff::tbRoleDetail* pDbData, const RoleOne& stRoleOne);

    /**
     * @brief
     * @param data
     * @return
     */
    virtual int SaveDB(proto_ff::tbRoleDetail* pDbData);

    virtual int SaveRoleSimpleInfo(proto_ff::Proto_RoleSimpleInfo* pDbData);

    /**
     * @brief
     * @return
     */
    virtual int LogicTick();

    virtual int OnRegister();

    /**
     * @brief 登陆入口
     * @return
     */
    virtual int OnLogin();

    /**
     * @brief 登出入口
     * @return
     */
    virtual int OnLogout();

    /**
     * @brief 掉线入口
     * @return
     */
    virtual int OnDisconnect();

    /**
     * @brief 重连入口
     * @return
     */
    virtual int OnReconnect();

    ////////////////////////////////// 每日每周刷新接口 ///////////////////////////////////
    /**
     * @brief 每日刷新接口
     * @return
     */
    virtual int DayTick();

    /**
     * @brief 每日4点/6点刷新接口
     * @return
     */
    virtual int DayOtherTick();

    /**
     * @brief 每周刷新接口
     * @return
     */
    virtual int WeekTick();

    /**
     * @brief 每月刷新接口
     * @return
     */
    virtual int MonthTick();

    /**
     * @brief 每秒定时回调
     * @return 0 表示成功，其他为错误码
     */
    virtual int SecTick();

    /**
     * @brief 每 5 秒定时回调
     * @return 0 表示成功，其他为错误码
     */
    virtual int FiveSecTick();

    /**
     * @brief 每分钟定时回调
     * @return 0 表示成功，其他为错误码
     */
    virtual int MinuteTick();

    /**
     * @brief 每 5 分钟定时回调
     * @return 0 表示成功，其他为错误码
     */
    virtual int FiveMinuteTick();

    /**
     * @brief 每小时定时回调
     * @return 0 表示成功，其他为错误码
     */
    virtual int HourTick();
public:
    virtual int MakePlayerDataCS(proto_ff::Proto_CSGetRoleRsp* pCSGetRoleRsp);
    virtual int MakeCityPlayerData(proto_ff::CityRoleInfo* pGCCityRoleInfo);
    virtual int MakeRoleCache(proto_ff::RoleOne* pRoleOne);
public:
    // 检查角色是否已初始化
    bool IsInit() const { return m_bIsInited; }

    // 获取角色基础信息的指针
    RoleBase* GetRoleBase() { return &m_stRoleBase; }

public:
    // 获取角色名称
    std::string GetRoleName() const { return m_stRoleBase.name.ToString(); }

    // 设置角色名称
    void SetRoleName(const std::string& name);

public:
    // 获取上次登录时间
    uint32_t GetLastLoginTime() const { return m_stRoleBase.last_login_time; }

    // 设置上次登录时间
    void SetLastLoginTime(uint32_t loginTime);

    // 获取上次退出时间
    uint32_t GetLastLogoutTime() const { return m_stRoleBase.last_logout_time; }

    // 设置上次退出时间
    void SetLastLogoutTime(uint32_t logoutTime);

public:
    // 获取角色创建时间
    uint32_t GetCreateTime() const { return m_stRoleBase.create_time; }

    // 设置角色创建时间
    void SetCreateTime(uint32_t createTime);

public:
    // 获取自动战斗状态
    bool GetAutoFight() const { return m_stRoleBase.auto_fight; }

    // 设置自动战斗状态
    void SetAutoFight(bool bAutoFight);

public:
    // 获取是否为公共基础属性
    bool GetIsPublicBase() const { return m_stRoleBase.is_public_base; }

    // 设置是否为公共基础属性
    void SetIsPublicBase(bool is_public_base);

public:
    // 获取是否为公共社交信息
    bool GetIsPublicSns() const { return m_stRoleBase.is_public_sns; }

    // 设置是否为公共社交信息
    void SetIsPublicSns(bool is_public_sns);

public:
    // 获取是否为公共装备信息
    bool GetIsPublicEquip() const { return m_stRoleBase.is_public_equip; }

    // 设置是否为公共装备信息
    void SetIsPublicEquip(bool is_public_equip);

public:
    // 获取是否为公共伙伴信息
    bool GetIsPublicPartner() const { return m_stRoleBase.is_public_partner; }

    // 设置是否为公共伙伴信息
    void SetIsPublicPartner(bool is_public_partner);

public:
    // 获取是否为公共符文信息
    bool GetIsPublicRune() const { return m_stRoleBase.is_public_rune; }

    // 设置是否为公共符文信息
    void SetIsPublicRune(bool is_public_rune);

public:
    // 获取电话号码
    int64_t GetPhoneNum() const { return m_stRoleBase.phone_num; }

    // 设置电话号码
    void SetPhoneNum(int64_t phone_num);

    // 检查是否有OpenID
    bool IsOpenID() const { return m_stRoleBase.open_id.size() > 0; }

    // 获取OpenID
    std::string GetOpenID() const { return m_stRoleBase.open_id.ToString(); }

    // 设置OpenID
    void SetOpenID(const std::string& open_id);

public:
    // 获取猎人职业类型
    ENHunterProfType GetHunterProf() const { return m_stRoleBase.hunter_prof; }

    // 设置猎人职业类型
    void SetHunterProf(ENHunterProfType type);

public:
    // 设置是否被大厅邀请
    void SetHallInvited(bool bIsHallInvited);

    // 检查角色是否被大厅邀请
    bool IsHallInvited() const { return m_stRoleBase.is_hall_invited; }

public:
    // 设置平台类型
    void SetPlatType(const Proto_PlatType plat_type);

    // 获取平台类型
    Proto_PlatType GetPlatType() const { return m_stRoleBase.plat_type; }

    // 获取世界ID
    uint32_t GetWorldID() const { return m_stRoleBase.world_id; }

public:
    // 获取角色性别
    enSexType GetSex() const { return m_stRoleBase.sex; }

    // 设置角色性别
    void SetSex(enSexType type);

public:
    // 获取角色职业
    enProfessionType GetProfession() const { return m_stRoleBase.profession; }

    // 设置角色职业
    void SetProfession(enProfessionType type);

public:
    // 获取角色经验
    uint64_t GetExp() const { return m_stRoleBase.exp; }

    // 设置角色经验
    void SetExp(uint64_t ullExp);

public:
    void IncreaseLevel();
    void SetLevel(uint16_t iLevel);
    uint16_t GetLevel() const { return m_stRoleBase.level; }

public:
    void SetCE(int iCE);

    //combat effectiveness,?????
    int GetCE() const { return m_stRoleBase.role_ce; }

public:
    int GetFirstRegOpenTime() const { return m_stRoleBase.first_reg_time; }

    void SetFirstRegOpenTime(int time);

public:
    Birthday* GetBirthday() { return &m_stRoleBase.birthday; }
    const Birthday* GetBirthday() const { return &m_stRoleBase.birthday; }

    void SetBirthday(const proto_ff::Birthday& birthday);
public:
    void MarkGSScoreModify() { m_needUpdateGS = true; }
    void MarkGSExpModify() { m_needUpdateExp = true; }
public:
    int MakeAttrCS(proto_ff::Proto_CSRoleAttrList* pRoleAttrList, bool bAll = false) const;
    int ClearAttrChangeFlag();
public:
    /* 交易数量增加函数 */
    void IncreaseTransNum();

    /* 交易数量减少函数 */
    void DecreaseTransNum();

    /* 重置CS消息序列号 */
    /* 该函数用于将CS消息的序列号重置为初始状态，以便开始新的消息序列 */
    void ResetCsMsgSeq();

    /* 增加CS消息序列号 */
    /* 该函数用于在发送CS消息后，增加消息的序列号，以确保消息的顺序性 */
    void IncCsMsgSeq();

    /* 获取当前CS消息序列号 */
    /* 该函数返回当前CS消息的序列号，用于标识和跟踪消息 */
    uint16_t GetCsMsgSeq();

    int GetTransNum() const { return m_iTransNum; }



protected:
    // 交易数量
    int m_iTransNum;

protected:
    // 是否已初始化
    bool m_bIsInited;

    // 角色基础信息
    RoleBase m_stRoleBase;
    RoleOne m_stRoleCache;

    // 序列号，用于状态同步
    uint32_t m_cs_seq;

    NFShmBitMap<EN_ROLE_ATTR_MAX> _has_bits_;
private:
    uint32_t m_lastUpdateExpTime;
    uint32_t m_lastUpdateGSTime;
    uint32_t m_lastUpdateAheadCostTime;
    uint32_t m_lastSycPlatDataTime;
    bool    m_needUpdateExp;
    bool    m_needUpdateGS;
};
